package com.yancloud.android.reflection.get;

import android.content.Context;
import android.util.Log;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MainServer extends Thread {
    public static ExecutorService executor = Executors.newFixedThreadPool(5);
    private static final String TAG = "MainServer";
    public static MainServer instance;
    public static final int mainPort=1715;
    private ServerSocket serverSocket;

    public static void main(Context c) {
        Log.d(TAG,"Start Server!");
        System.out.println("[DOIP] Start Main Server");
        instance = new MainServer();
        instance.start();
    }

    public void run() {
        int listeningPort = mainPort;
        while (true) {
            try {
                serverSocket = new ServerSocket(listeningPort);
                break;
            } catch (Exception e) {
                listeningPort++;
            }
        }
        Log.d(TAG, "port:" + listeningPort);
        while (true) {
            Socket client;
            try {
                client = serverSocket.accept();
                executor.execute(new HandlerThread(client));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private class HandlerThread implements Runnable {
        private Socket socket;

        public HandlerThread(Socket client) {
            socket = client;
        }

        public void run() {
            try {
                ObjectInputStream input = new ObjectInputStream(
                        socket.getInputStream());
                GetMessage message = (GetMessage) input.readObject();
                ObjectOutputStream out = new ObjectOutputStream(
                        socket.getOutputStream());
                String ret = handle(message);

                out.writeObject(ret);
                out.flush();
                out.close();
                input.close();
            } catch (Throwable e) {
                System.out.println("Exception: " + e.getMessage());
                e.printStackTrace();
            } finally {
                try {
                    if (socket != null)
                        socket.close();
                } catch (Exception e) {
                    socket = null;
                    Log.d(TAG, "Server Error:" + e.getMessage());
                }
            }
        }


    }
    public static String handle(GetMessage message) {
        try {
            String ret;
            ret = CMDManager.handle(message.pkgName,message.method,message.arg);
            return ret;
        } catch (Throwable e) {
            ByteArrayOutputStream bo = new ByteArrayOutputStream();
            e.printStackTrace(new PrintStream(bo));
            return "{ \"msg\":\"" + bo.toString() + "\"}";
        }
    }
}